
#include "Calculator.h"


class CalculatorForm :
	public Osp::Ui::Controls::Form,
	public Osp::Ui::IActionEventListener
{
protected:
		Osp::Ui::Controls::Panel*  __pGridPanel;

public:
	static const int MAX_PRINTABLE_CHARS = 8;

	static const int ID_BTN_DOT 		= 104;
	static const int ID_BTN_BACK 		= 105;
	static const int ID_BTN_EQUAL 		= 106;

	static const int ID_BTN_CLEAR 		= 107;

	static const int ID_BTN_PLUS 		= 109;
	static const int ID_BTN_MINUS 		= 110;

	static const int ID_BTN_MULTIPLY 	= 111;
	static const int ID_BTN_DIVIDE		= 112;
	static const int ID_BTN_SIGN 		= 113;
	static const int ID_BTN_UNKNOWNOP	= 114;

public:
	CalculatorForm(void);
	~CalculatorForm(void);

public:
	result Construct();

	virtual result OnInitializing(void);
	virtual result OnTerminating(void);
	virtual result OnDraw(void);
	virtual void OnActionPerformed(const Osp::Ui::Control& source, int actionId);

private:
	void CreateButtons(void);

	void RefineNumber(Osp::Base::String & strNumber, bool isSwapSign = false);
	void SetOperandByContext(const Osp::Base::String & strOperand);

private:

	Osp::Base::String			__strBufferForPrint;
	Osp::Base::String			__strBufferForMC;
	Osp::Ui::Controls::Label*	__pLabelPrint;


	// Nested class : This class performs real calculation.
	class CalculatorModel{
		public:
			CalculatorModel() : __nOperator(ID_BTN_UNKNOWNOP), __CalcMode(enMODE_READY) { }
			void	SetOperand1(const Osp::Base::String & strOperand);
			void	SetOperand2(const Osp::Base::String & strOperand);
			void	SetOperator(int nType);
			result	Calc(Osp::Base::String & strResult);
			void	Reset();

			bool	IsReady() const;
			bool	IsOperand1() const;
			bool	IsOperator() const;
			bool	IsOperand2() const;
			bool	IsFinished() const;

			bool	isOpJustOn;

		private:
			enum CALCULATE_MODE {
				enMODE_READY,			// Initial State
				enMODE_OPERAND1,
				enMODE_OPERATOR,
				enMODE_OPERAND2,
				enMODE_FINISHED,		// Finished calculation
				enMODE_ERROR,
			};

			Osp::Base::String		__strOperand1;
			Osp::Base::String		__strOperand2;
			Osp::Base::String		__strBackupResult;
			int				__nOperator;
			CALCULATE_MODE	__CalcMode;			// State Indicator of CalculatorModel
	} __Calculator;
};
